package model;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * This class is an implementation of Element that represents
 * stocks and their prices.
 * 
 * @author Group 8
 * 
 */
public class StockElement implements Element {
    private static final String OPEN = "open";
    private String myName;
    private String myID;
    private Map<String, List<Double>> myMap;
    private List<Double> myValues;
    private double myCurrentValue;
    private double myRelativeSize;
    @SuppressWarnings("unused")
    private String myCurrentSpec;

    /**
     * Constructor for stock element.
     * 
     * @param name name of the element
     * @param id unique ID of the element
     * @param values values of the element[key:label, List: list of values]
     */
    public StockElement (String name, String id,
            Map<String, List<Double>> values) {
        setName(name);
        setID(id);
        myMap = values;
        myCurrentSpec = OPEN;
        myValues = myMap.get(OPEN);
        myCurrentValue = myValues.get(0);
        myRelativeSize = -1;
    }

    /**
     * Returns name of element.
     */
    public String getName () {
        return myName;
    }

    /**
     * Returns data from 1 to [range].
     * 
     * @param range the maximum value of data
     */
    public List<Double> getDataRange (int range) {
        List<Double> d = new LinkedList<Double>();
        if (range > myValues.size()) {
            throw new LoadElementException(
                "Requested Range goes beyond Limits of Data");
        }
        for (int k = 1; k <= range; k++) {
            d.add(myValues.get(k - 1));
        }
        return d;
    }

    /**
     * Sets name of element.
     * 
     * @param name new name
     */
    public void setName (String name) {
        myName = name;
    }

    /**
     * Checks to see if the map contains a certain string. If not,
     * prints an error message.
     * 
     * @param type string to be checked
     */
    public void specifyData (String type) {
        List<Double> newList = myMap.get(type);
        if (newList == null) {
            System.out.println(
                    "The Stock Data you specified is not available. " +
                            "Try {'open', 'close', 'high', 'low'}");
            return;
        }
        myValues = newList;
        myCurrentSpec = type;
    }

    /**
     * Returns ID of element.
     */
    public String getID () {
        return myID;
    }

    /**
     * Sets ID of element.
     * 
     * @param id new ID
     */
    public void setID (String id) {
        myID = id;
    }

    /**
     * Returns value of element.
     */
    public double getValue () {
        return myCurrentValue;
    }

    /**
     * Returns list of values for the element.
     */
    public List<Double> getValueList () {
        return myValues;
    }

    /**
     * Returns the size of the element relative to all
     * other elements.
     */
    public double getRelativeSize () {
        return myRelativeSize;
    }

    /**
     * Set the relative size of the element.
     * 
     * @param p new relative size
     */
    public void setRelativeSize (double p) {
        myRelativeSize = p;
    }

    /**
     * Resets the list of values for the stock to a given list.
     * 
     * @param newList new values
     */
    public void setValueList (List<Double> newList) {
        myValues.clear();
        myValues.addAll(newList);
        myCurrentValue = myValues.get(0);
    }
}
